package cn.itnanls.Controller;

import cn.itnanls.entity.User;
import cn.itnanls.exception.BusinessException;
import cn.itnanls.exception.ParamIllegalException;
import cn.itnanls.util.R;
import cn.itnanls.util.ResultCode;
import com.alibaba.fastjson.JSONObject;
import com.sun.deploy.net.HttpResponse;
import com.sun.deploy.net.URLEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.RequestWrapper;
import java.io.*;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Ding
 */
@RequestMapping("/user/")
@Controller
public class UserController {
    @GetMapping("get/{id}")
    @ResponseBody
//    ResetFul风格获取资源
    public User getUserByid(@PathVariable int id){
        return new User(1,"itnanlaoshi","123");
    }

//    匹配中的占位符
//    ？:一个字符
//    *：0个或者多个字符
//    **：多个片段，所谓片段/User 这种叫片段
//    甚至是正则表达式或者变量  这一段写给RequestMapping

    @RequestMapping("showUser")
    public void showUser(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response,
                           User user) throws Exception {
        System.out.println(user);
       if(!user.getUsername().equals( "zs" )){
           System.out.println("啪错误啦");
           throw new BusinessException( ResultCode.Business_ERROE );
       }
        System.out.println("运行到这里了");
    }
//    mv Model就是数据而View就是视图就是界面
//  如何实现model和view分离
//  首先要把返回值改成String，如果只需要视图这里就返回对应的名字,返回的字符串就是View的名字
//  如果需要model，我们就把对应的model作为参数传入。但model只能用一次，请求转发也不能保存model
//  如果不需要视图只需要返回null值

    /*返回一个json值*/
//    consumes用于指定我们请求的类型
//    produce是用于设置我们response的类型
    @RequestMapping(value = "/addUser",produces = "application/json;charset=utf-8")
    public void addUser(Model model, HttpServletResponse response) throws Exception {
        User user = new User(1,"zhangsan","123");
        String userstr = JSONObject.toJSONString( user );
        response.getWriter().write( userstr );
        response.getWriter().close();
    }
    //从requestBody中接收json对象并且自动封装成为User对象
    @RequestMapping(value = "testJson" )
    //把对象换成json体让后放在response里
    @ResponseBody
    public User testJson(@RequestBody User user){
       user.setPassword( "123456" );
       return user;
    }
    @RequestMapping(value = "testMapping" ,params = {"username=zs","password=lisi"},method = RequestMethod.POST)
    public String testMapping(){
        return "user";
    }

    /**
     * 处理异常
     * 这个Validate是会根据注解来检验前端的参数是否合法
     * @param user
     * @return
     */
    @RequestMapping(value = "testDate" )
    @ResponseBody
    public User testDate(@Validated User user,BindingResult result){
        List<ObjectError> Alleroor = result.getAllErrors();
        if(Alleroor.size()>0){
            System.out.println("抛异常");
            Map<String,String > errrors = new HashMap<>(4);
            for (ObjectError objectError : Alleroor) {
                String code  = objectError.getCode();
                String meg = objectError.getDefaultMessage();
                errrors.put( code,meg );
            }
            throw new ParamIllegalException( ResultCode.ParamIllegal_ERROR,errrors );
        }
        System.out.println("我在运行！");
        return user;
    }
    /**
     * 上传文件
     */
    @RequestMapping("upload")
    @ResponseBody
    public R upload(@RequestParam("file")CommonsMultipartFile file) throws IOException {
        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();
        System.out.println("上传文件名 : "+uploadFileName);

        //上传路径保存设置
        String path = "D:\\project\\JAVAproject\\test-mybatis\\spring-mvc\\src\\main\\upload";
        //如果路径不存在，创建一个
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址："+realPath);
        //就问香不香，就和你写读流一样
        file.transferTo(new File(path+"/"+uploadFileName));
        return R.of( ResultCode.SUCCESS );
    }
    /**
     * 下载文件
     */
    @RequestMapping("download")
    @ResponseBody
    public R download(HttpServletResponse response) throws IOException {
        // 这个文件名是前端传给你的要下载的图片的id
        // 然后根据id去数据库查询出对应的文件的相关信息，包括url，文件名等
            String  fileName = "1.png";
            System.out.println("方法正在运行...");
            //1、设置response 响应头，处理中文名字乱码问题
            response.reset(); //设置页面不缓存,清空buffer
            response.setCharacterEncoding("UTF-8"); //字符编码
            response.setContentType("multipart/form-data"); //二进制传输数据
            //设置响应头，就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名。
            //Content-Disposition属性有两种类型：inline 和 attachment
            //inline ：将文件内容直接显示在页面
            //attachment：弹出对话框让用户下载具体例子：
        response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
        //输出流，输出给浏览器的
        ServletOutputStream outputStream =response.getOutputStream();
        //输入流，从我这个电脑输送给服务器的，参数是文件的路径
        InputStream inputStream = new FileInputStream( "D:\\project\\JAVAproject\\test-mybatis\\spring-mvc\\src\\main\\upload\\1.png" );

        //buf是用来做缓存的，越大就越流畅，但对服务器性能要求越高。
        byte [] bytes = new byte[1024*20];
        int lenth;
        while ((lenth = inputStream.read(bytes))!=-1){
            System.out.println(bytes);
            outputStream.write( bytes,0,lenth );
        }
        outputStream.flush();
        outputStream.close();
        return R.of( ResultCode.SUCCESS );
    }
}
